package cn.nubia.admin.file;

import cn.nubia.admin.common.ftp.FtpClientUtil;
import cn.nubia.admin.common.springmvc.SpringContextLoader;
import cn.nubia.admin.common.utils.DateUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by justin on 15/7/2.
 */
public class FileManager {

    public static final String UPLOAD = "upload/";

    public static final String ROOT = System.getProperty("web.root") + UPLOAD;

    public static final String ABSPATH_APK = "apk";
    public static final String ABSPATH_APK_ICON = "icon";
    public static final String ABSPATH_APK_AD = "ad";
    public static final String ABSPATH_SCREENSHOT = "screenshot";
    public static final String ABSPATH_PIC = "picture";


    public static String getAbsFile(String localFilePath) {
        return File.separator + UPLOAD + localFilePath.substring(ROOT.length());
    }

    public static String getAbsDir(String localFilePath) {
        String fileName = File.separator + UPLOAD + localFilePath.substring(ROOT.length());
        return fileName.substring(0, fileName.lastIndexOf(File.separator) + 1);
    }

    public static String getFileName(String filePath) {
        return filePath.substring(filePath.lastIndexOf(File.separator) + 1, filePath.length());
    }

    public static String getLocalPath(String absPath) {
        return System.getProperty("web.root") + absPath;
    }

    public static String getLocalDir(String absPath) {
        String dir = ROOT + absPath + File.separator + getDatePath();
        try {
            FileUtils.forceMkdir(new File(dir));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dir;
    }

    public static String getLocalFile(String absPath, String fileName) {
        String dir = ROOT + absPath + File.separator + getDatePath();
        try {
            FileUtils.forceMkdir(new File(dir));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dir + fileName;
    }


    public static String getAbsClientFileName(String apkFilePath) {
        return "/upload/" + apkFilePath.substring(ROOT.length());
    }

    public static String getTimeStampFileName(String orignFileName) {
        return DateUtil.getCurrentTime() + orignFileName.substring(orignFileName.lastIndexOf("."));
    }

    /**
     * 获取时间的路径如2015/7/2/
     *
     * @return
     */
    public static String getDatePath() {
        Calendar now = Calendar.getInstance();
        return now.get(Calendar.YEAR) + File.separator + (now.get(Calendar.MONTH) + 1) + File.separator + now.get(Calendar.DAY_OF_MONTH)
                + File.separator + now.getTimeInMillis() + File.separator;
    }

    /**
     * 上传文件
     *
     * @param path
     * @param multipartFile
     * @throws IOException
     */
    public static void uploadfiles(String path, MultipartFile multipartFile) throws IOException {
        byte[] b = new byte[(int) multipartFile.getSize()];
        int read = 0;
        int i = 0;
        InputStream is = multipartFile.getInputStream();
        while ((read = is.read()) != -1) {
            b[i] = (byte) read;
            i++;
        }
        is.close();
        FileUtils.writeByteArrayToFile(new File(path), b);
    }

    /**
     * 上传文件
     *
     * @param path
     * @throws IOException
     */
    public static void uploadfiles(String path, InputStream inputStream) throws IOException {
        byte[] b = new byte[inputStream.available()];
        int read = 0;
        int i = 0;
        while ((read = inputStream.read()) != -1) {
            b[i] = (byte) read;
            i++;
        }
        inputStream.close();
        FileUtils.writeByteArrayToFile(new File(path), b);
    }

    public static String getMd5ByFile(File file) {
        String value = null;
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(byteBuffer);
            BigInteger bi = new BigInteger(1, md5.digest());
            value = bi.toString(16);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return value;
    }


    /***
     * 上传文件
     *
     * @return
     * @throws IOException
     */
    public static String uploadFile(String url) throws IOException {
        String filename = FileManager.getTimeStampFileName(getFileNameByUrl(url));
        String picLocalFileName = FileManager.getLocalFile(FileManager.ABSPATH_PIC, filename);
        String absPicPath = FileManager.getAbsFile(picLocalFileName);
        try {
            FtpClientUtil ftpClientUtil = (FtpClientUtil) SpringContextLoader.getBean("ftpClientUtil");
            downLoadFromUrl(url,picLocalFileName);
//            FileManager.uploadfiles(picLocalFileName, is);// 上传文件
            String asbPicFileDir = FileManager.getAbsDir(picLocalFileName);
            if (!ftpClientUtil.isDirExist(asbPicFileDir)) ftpClientUtil.createDirs(asbPicFileDir);
            if (!ftpClientUtil.addFile(asbPicFileDir, FileManager.getFileName(picLocalFileName), new File(picLocalFileName))) {
                return url;
            }
            FileUtils.forceDelete(new File(picLocalFileName).getParentFile());
            return absPicPath;
        } catch (Exception e) {
            e.printStackTrace();
            return absPicPath;
        }
    }


    /**
     * 从网络Url中下载文件
     *
     * @param urlStr
     * @throws IOException
     */
    public static void downLoadFromUrl(String urlStr,String localFileName) throws IOException {
        try {
            URL url = new URL(urlStr);
            DataInputStream dataInputStream = new DataInputStream(url.openStream());
            FileOutputStream fileOutputStream = new FileOutputStream(new File(localFileName));

            byte[] buffer = new byte[1024];
            int length;

            while ((length = dataInputStream.read(buffer)) > 0) {
                fileOutputStream.write(buffer, 0, length);
            }

            dataInputStream.close();
            fileOutputStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
//
//
//
//
//        URL url = new URL(urlStr);
//        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//        //设置超时间为3秒
//        conn.setConnectTimeout(1000 * 1000);
//        //防止屏蔽程序抓取而返回403错误
//        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//        //得到输入流
//        return conn.getInputStream();
    }


    protected static String getFileNameByUrl(String url) {
        String filename = "";
        boolean isok = false;
        // 从UrlConnection中获取文件名称
        try {
            URL myURL = new URL(url);

            URLConnection conn = myURL.openConnection();
            if (conn == null) {
                return null;
            }
            Map<String, List<String>> hf = conn.getHeaderFields();
            if (hf == null) {
                return null;
            }
            Set<String> key = hf.keySet();
            if (key == null) {
                return null;
            }
            // Log.i("test", "getContentType:" + conn.getContentType() + ",Url:"
            // + conn.getURL().toString());
            for (String skey : key) {
                List<String> values = hf.get(skey);
                for (String value : values) {
                    String result;
                    try {
                        result = new String(value.getBytes("ISO-8859-1"), "GBK");
                        int location = result.indexOf("filename");
                        if (location >= 0) {
                            result = result.substring(location
                                    + "filename".length());
                            filename = result
                                    .substring(result.indexOf("=") + 2,result.length()-1);
                            isok = true;
                        }
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }// ISO-8859-1 UTF-8 gb2312
                }
                if (isok) {
                    break;
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 从路径中获取
        if (filename == null || "".equals(filename)) {
            int qIndex = url.indexOf("?");
            if(qIndex>0){
                url = url.substring(0,url.indexOf("?"));
            }
            filename = url.substring(url.lastIndexOf("/") + 1);
        }
        return filename;
    }


}
